package ControlLayer;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Set;

import DBLayer.DBConnection;

import DBLayer.DBSaleLine;

import DBLayer.IFDBSaleLine;

import DBLayer.DBSale;

import DBLayer.IFDBSale;

import ModelLayer.Customer;
import ModelLayer.Enum;
import ModelLayer.Invoice;
import ModelLayer.Product;
import ModelLayer.Sale;
import ModelLayer.SaleLine;

public class SaleCtr {
	private CustomerCtr customerCtr;
	private InvoiceCtr invoiceCtr;

	public SaleCtr() {
		customerCtr = new CustomerCtr();
		invoiceCtr = new InvoiceCtr();
	}

	public Sale getSale(int saleId) {
		IFDBSale dbSale = new DBSale();
		return dbSale.getSale(saleId, true);
	}

	// TODO create local sale object and update it to database
	public int createSale(int invoiceNo, Date date, Date deliverDate,
			double totalPrice, String deliveryStatus, int customerId,
			HashMap<Integer, Integer> products) {
		//add sale
		int saleId = insertSale(invoiceNo, date, deliverDate, totalPrice,
				deliveryStatus, customerId);
		//add saleline
		Set<Integer> productIdSet = products.keySet();
		for (Integer productId : productIdSet) {
			insertSaleLine(saleId, productId, products.get(productId));
		}
		//update invoice
		Invoice invoice = invoiceCtr.getInvoice(invoiceNo);
		double pirce = totalPrice + invoice.getTotalPrice();
		invoiceCtr.updateInvoice(invoiceNo, customerId, invoice.getPayDate(), pirce, invoice.isDelivery(), invoice.isCashOnDelivery());
		return saleId;
	}

	public int updateSaleTotalPrice(int saleId, double price) {

		IFDBSale dbSale = new DBSale();
		Sale sale = getSale(saleId);
		sale.setTotalPrice(price);
		return dbSale.updateSale(sale);
	}

	public int insertSale(int invoiceNo, Date date, Date deliverDate,
			double totalPrice, String deliveryStatus, int customerId) {
		int saleId = 0;
		Sale sale = new Sale();
		sale.setInvoice(new Invoice(invoiceNo));
		sale.setDeliverStatus(Enum.valueOf(deliveryStatus));
		sale.setCustomer(new Customer(customerId));
		sale.setDeliveryDate(deliverDate);
		sale.setDate(date);
		sale.setTotalPrice(totalPrice);
		try {
			DBConnection.startTransaction();
			DBSale dbSale = new DBSale();
			saleId = dbSale.insertSale(sale);
			DBConnection.commitTransaction();
		} catch (Exception e) {
			DBConnection.rollbackTransaction();
		}
		return saleId;
	}

	public ArrayList<Sale> getAllSale() {
		IFDBSale dbSale = new DBSale();
		ArrayList<Sale> sales = new ArrayList<Sale>();
		sales = dbSale.getAllSale(false);
		return sales;
	}

	public void updateSale(int saleId, int invoiceNo, Date date, Date deliverDate,
			String deliverStatus, int customerId, double totalPrice, HashMap<Integer, Integer> products) throws Exception {
		IFDBSale dbSale = new DBSale();
		Sale sale = new Sale();
		sale.setSaleId(saleId);
		sale.setDeliveryDate(deliverDate);
		sale.setInvoice(new Invoice(invoiceNo));
		sale.setDate(date);
		sale.setCustomer(new Customer(customerId));
		sale.setDeliverStatus(Enum.valueOf(deliverStatus));
		sale.setCustomer(customerCtr.getCustomer(customerId));
		sale.setTotalPrice(totalPrice);
		
		deleteSaleLinesForSale(saleId);
		Set<Integer> productIdSet = products.keySet();
		for (Integer productId : productIdSet) {
			insertSaleLine(saleId, productId, products.get(productId));
		}
		int rc = dbSale.updateSale(sale);
		 if (rc == -1) {
			 throw new Exception ("Sale is not updated correct");
		 }

	}
	
	public int deleteSale(int saleId) {
		//delete salelines first before delete sale
		deleteSaleLinesForSale(saleId);
		IFDBSale dbSale = new DBSale();
		int rc = dbSale.deleteSale(saleId);
		if (rc != -1)
			return 1;
		else return 2;
	}
	
	public double getSalePrice(int saleId) {
		return getSale(saleId).getTotalPrice();
	}

	

	public void insertSaleLine(int saleId, int productId, int quantity) {

		SaleLine saleline = new SaleLine();
		saleline.setProduct(new Product(productId));
		saleline.setSale(new Sale(saleId));
		saleline.setQuantity(quantity);

		try {
			DBConnection.startTransaction();
			DBSaleLine dbSaleLine = new DBSaleLine();
			dbSaleLine.insertSaleLine(saleline);
			DBConnection.commitTransaction();
		} catch (Exception e) {
			DBConnection.rollbackTransaction();
		}

	}

	public ArrayList<SaleLine> getSaleLinesForSale(int saleId) {
		IFDBSaleLine dbSaleline = new DBSaleLine();
		ArrayList<SaleLine> salelins = new ArrayList<SaleLine>();
		salelins = dbSaleline.getAllSaleLineForSale(saleId, false);
		return salelins;
	}

	public void deleteSaleLinesForSale(int saleId) {
		IFDBSaleLine dbSaleline = new DBSaleLine();
		dbSaleline.deleteSalelinesForSale(saleId);
	}

}
